package org.xbrlapi.aspects;

import java.io.Serializable;
import java.util.List;

import org.xbrlapi.data.Store;
import org.xbrlapi.utilities.XBRLException;

/**
 * <h2>Labeller</h2>
 * <p/>
 * <p>
 * Classes implementing the Labeller interface are intended to provide access to
 * labels for aspects and their values.
 * </p>
 * <p/>
 * <p>
 * The implementation of a labeller will be specific to one or more particular types of aspect.
 * The constructor for the labeller MUST throw an exception if the labeller is initialised
 * with an aspect that is not of the right type.
 * </p>
 *
 * @author Geoff Shuetrim (geoff@galexy.net)
 */
public interface Labeller extends Serializable {

    /**
     * @return the aspect that this is a labeller for.
     */
    public Aspect getAspect();

    /**
     * @return the domain for the aspect that this is a labeller for.
     */
    public Domain getDomain();

    /**
     * @return the store underpinning the domain for the aspect that this is a labeller for.
     */
    public Store getStore() throws XBRLException;

    /**
     * @param locale       The locale (language code etc) of the label. Set to null if the label is not locale dependent.
     * @param resourceRole The resource role of the XLink resource providing the label.  Set to null if the label
     *                     does not depend on the resource role.
     * @param linkRole     The link role of the extended link network that is to be analysed to obtain the label. Set to
     *                     null if the label does not depend on the link role.
     * @return the label for the aspect based upon the given parameters, falling back to labels generated
     * by superclass labellers where necessary, eventually using just the aspect ID
     * if that is all that is available.
     */
    public String getAspectLabel(String locale, String resourceRole, String linkRole);

    /**
     * @param locales       The locales (language code etc) of the label. Set to null if the label is not locale dependent.
     * @param resourceRoles The resource roles of the XLink resource providing the label.  Set to null if the label
     *                      does not depend on the resource role.
     * @param linkRoles     The link roles of the extended link network that is to be analysed to obtain the label. Set to
     *                      null if the label does not depend on the link role.
     * @return the label for the aspect based upon the given parameters, falling back to labels generated
     * by superclass labellers where necessary, eventually using just the aspect ID
     * if that is all that is available.
     */
    public String getAspectLabelGivenLists(List<String> locales, List<String> resourceRoles, List<String> linkRoles);


    /**
     * @param locale       The locale (language code etc) of the label. Set to null if the label is not locale dependent.
     * @param resourceRole The resource role of the XLink resource providing the label.  Set to null if the label
     *                     does not depend on the resource role.
     * @param linkRole     The link role of the extended link network that is to be analysed to obtain the label. Set to
     *                     null if the label does not depend on the link role.
     * @return the label for the aspect based upon the given parameters or null if no such label exists.
     */
    public String getAspectLabelWithoutFallback(String locale, String resourceRole, String linkRole);

    /**
     * @param value        The aspect value to get a label for.
     * @param locale       The locale (language code) of the label. This can be set to
     *                     null if the label is not locale dependent.
     * @param resourceRole The resource role of the XLink resource providing the label.
     *                     This can be set to null if the label does not depend on the
     *                     resource role.
     * @param linkRole     The link role of the extended link network that is to be
     *                     analysed to obtain the label. This can be set to null if the
     *                     label does not depend on the link role.
     * @return the label for the aspect value based upon the given parameters,
     * falling back to labels generated by superclass labellers where
     * necessary, eventually using just the aspect value ID if that is
     * all that is available.
     */
    public String getAspectValueLabel(AspectValue value, String locale, String resourceRole, String linkRole);

    /**
     * @param value         The aspect value to get the label for.
     * @param locales       The list of locales, from first (most preferred) to last
     *                      (least preferred) or null if locale is not a selection
     *                      criterion.
     * @param resourceRoles The list of label resource roles, from first (most preferred)
     *                      to last (least preferred) or null if resource role is not a
     *                      selection criterion.
     * @param linkRoles     The list of extended link roles, from first (most preferred)
     *                      to last (least preferred) or null if link role is not a
     *                      selection criterion.
     * @return the label that best fits the selection criteria, falling back to
     * the label provided by the superclass (eventually this is just the
     * aspect value ID in a worst case situation).
     * <p/>
     * <p>
     * The selection criteria are prioritised as follows: try hardest to
     * match locale. After that, try hardest to match resource role. Try
     * least hard to match the extended link role.
     * </p>
     */
    public String getAspectValueLabelGivenLists(AspectValue value, List<String> locales,
                                                List<String> resourceRoles, List<String> linkRoles);

    /**
     * @param value        The aspect value to get a label for.
     * @param locale       The locale (language code) of the label. This can be set to
     *                     null if the label is not locale dependent.
     * @param resourceRole The resource role of the XLink resource providing the label.
     *                     This can be set to null if the label does not depend on the
     *                     resource role.
     * @param linkRole     The link role of the extended link network that is to be
     *                     analysed to obtain the label. This can be set to null if the
     *                     label does not depend on the link role.
     * @return the label for the aspect value based upon the given parameters,
     * without falling back to the label obtained by the superclass, if
     * no label can be obtained.  If no label is obtained, a value of null
     * is returned.
     */
    public String getAspectValueLabelWithoutFallback(AspectValue value, String locale, String resourceRole, String linkRole);

    /**
     * @return a new labeller that is a duplicate of this one.
     * The aspect is not duplicated (the original is used).
     * @throws XBRLException if the labeller does not support duplication.
     */
    public Labeller duplicate() throws XBRLException;

}
